package com.tapstitch.scm.common.core.repository.condition;

import com.alibaba.fastjson.annotation.JSONField;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

public class PageIterator<T> implements Serializable {

    private static final long serialVersionUID = 8102012822572335930L;
    private static final int MAX_PAGE_SIZE = 1000;

    private int pageNum;
    private int pageSize;
    private int totalPage;
    private long totalCount;
    private List<T> data;

    public static <T> PageIterator<T> create(int page, int pageSize, long totalCount) {
        return create(page, pageSize, totalCount, null);
    }

    public static <T> PageIterator<T> create(int pageNum, int pageSize, long totalCount, List<T> data) {
        PageIterator<T> instance = new PageIterator<>();
        instance.setPageNum(Math.max(pageNum, 1));
        instance.setPageSize(pageSize);
        instance.setTotalCount(totalCount);
        instance.setTotalPage((int) Math.ceil((double) totalCount / (double) pageSize));
        instance.setData(data);
        return instance;
    }

    public static <T> PageIterator<T> empty() {
        return PageIterator.create(0,0,0, Collections.emptyList());
    }

    @JSONField(serialize = false)
    public int getOffset() {
        return (pageNum - 1) * pageSize;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int page) {
        this.pageNum = Math.max(page, 1);
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        if (pageSize < 1) {
            this.pageSize = 1;
        } else {
            this.pageSize = Math.min(pageSize, MAX_PAGE_SIZE);
        }
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(long totalCount) {
        this.totalCount = totalCount;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }
}
